﻿using NModbus; // 替换 NModbus.Device
using NLog; 
using System; 
using System.Net.Sockets; 
using System.Windows.Forms; 

namespace autoctrl.utils 
{ 
  public class PlcModbusClient : IDisposable 
  { 
    private TcpClient tcpClient; 
    private IModbusMaster modbusMaster; // 修改类型为 IModbusMaster
    private string slaveIp; 
    private int modbusPort = 502; 
    private static readonly Logger logger = LogManager.GetCurrentClassLogger(); 

    public PlcModbusClient(string _slaveIp, int _modbusPort = 502) 
    { 
      slaveIp = _slaveIp; 
      modbusPort = _modbusPort; 
    } 


    public bool Connect() 
    { 
      try 
      { 
        if (tcpClient?.Connected == true) return true; 
        tcpClient = new TcpClient(); 
        tcpClient.Connect(slaveIp, modbusPort); 
        // 创建 Modbus TCP 主站
        var factory = new ModbusFactory(); 
        modbusMaster = factory.CreateMaster(tcpClient); 
        return true; 
      } 
      catch (Exception ex) 
      { 
        logger.Error(ex.StackTrace); 
        MessageBox.Show($"连接PLC控制器失败：{ex.Message}"); 
        return false; 
      } 
    } 

    // 读取PLC线圈（M元件）
    public bool ReadCoil(ushort coilAddr,byte slaveAddr = 1)
    {
      try
      {
        if (tcpClient?.Connected != true) return false;

        // 读取1个线圈状态（功能码0x01）
        bool[] coils = modbusMaster.ReadCoils(slaveAddr, coilAddr, 1);
        return coils[0];
      }
      catch (Exception ex)
      {
        MessageBox.Show($"读取线圈M{coilAddr}失败：{ex.Message}");
        return false;
      }
    }

    // 写入PLC线圈（M元件）
    public void WriteCoil(ushort coilAddress, bool value, byte slaveAddr = 1)
    {
      try
      {
        if (tcpClient?.Connected != true) return;

        // 写入单个线圈（功能码0x05）
        modbusMaster.WriteSingleCoil(slaveAddr, coilAddress, value);
      }
      catch (Exception ex)
      {
        MessageBox.Show($"写入线圈M{coilAddress}失败：{ex.Message}");
      }
    }

    // 读取PLC寄存器（D元件）
    public ushort[] ReadRegisters(ushort startAddress, ushort count, byte slaveAddr = 1)
    {
      try
      {
        if (tcpClient?.Connected != true) return null;
        // 读取多个寄存器（功能码0x03）
        return modbusMaster.ReadHoldingRegisters(slaveAddr, startAddress, count);
      }
      catch (Exception ex)
      {
        MessageBox.Show($"读取寄存器D{startAddress}失败：{ex.Message}");
        return null;
      }
    }

    public void WriteRegisters(ushort startAddress, ushort[] values, byte slaveAddr = 1)
    {
      try
      {
        if (tcpClient?.Connected != true) return;

        modbusMaster.WriteMultipleRegisters(slaveAddr, startAddress, values);
      }
      catch (Exception ex)
      {
        MessageBox.Show($"写入寄存器D{startAddress}失败：{ex.Message}");
      }
    }

    public void Dispose()
    {
      if (tcpClient?.Connected == true) tcpClient.Close();
      tcpClient?.Dispose();
    }
  }
}